package com.hvgroup.modules.sanic.service.impl.chat;

import com.hvgroup.modules.sanic.domain.qo.QaQuestionQuery;
import lombok.Builder;
import lombok.Getter;
import lombok.ToString;

import java.util.Optional;
import java.util.function.Function;

/**
 * 流式事件主状态对象
 * 记录业务数据、流内递进文本、步骤等
 */
@Getter
@Builder
@ToString
public class EventData {
    /**
     * 事件附加数据（可选）
     */
    private final Object data;
    /**
     * 业务流核心文本内容（推送给前端或落库）
     */
    private final String text;
    /**
     * 业务原始请求参数，便于全链追踪
     */
    private final QaQuestionQuery busData;
    /**
     * 流内步骤计数器（递增，区别每次有效变更）
     */
    private final Integer step;

    /**
     * 全局开始时间
     */
    private final Long requestTimestamp;
    /**
     * 本步开始（或上一步结束）
     */
    private final Long stepStartTimestamp;

    private final EventData preData;

    /**
     * 步骤递增方法，null安全处理
     */
    public Integer incr() {
        return step == null ? 0 : step + 1;
    }

    /**
     * 步骤getter，null时返回0
     */
    public int getStep() {
        return step == null ? 0 : step;
    }

    public boolean hasPreData() {
        return preData != null;
    }

    // EventData data = buildNext(preData).apply(buildData.text().incr()...)
    public static Function<EventData.EventDataBuilder, EventData> buildNext(EventData pre) {
        if (pre == null) {
            return cur -> cur
                    .requestTimestamp(System.currentTimeMillis())
                    .stepStartTimestamp(System.currentTimeMillis())
                    .step(0)
                    .build();
        }
        return cur -> cur
                .text(Optional.ofNullable(cur.text).orElse(pre.getText()))
                .data(Optional.ofNullable(cur.data).orElse(pre.getData()))
                .busData(Optional.ofNullable(cur.busData).orElse(pre.getBusData()))
                .preData(pre)
                .step(pre.incr())
                .requestTimestamp(Optional.ofNullable(pre.requestTimestamp).orElse(System.currentTimeMillis()))
                .stepStartTimestamp(System.currentTimeMillis())
                .build();
    }


}
